#include "Settings.h"
#include <wx/imaglist.h>
#include <wx/artprov.h>
#include <wx/bookctrl.h>
#include <wx/textctrl.h>
#include "../StdUserInterfaceModule/AccountPanel.h"

#ifdef __WXGTK__
	#include <gtk/gtk.h>
#endif

namespace Impp
{

IMPLEMENT_CLASS(SettingsDialog, wxPropertySheetDialog)

BEGIN_EVENT_TABLE(SettingsDialog, wxPropertySheetDialog)
	EVT_BUTTON(wxID_OK, SettingsDialog::onOk)
END_EVENT_TABLE()

SettingsDialog::SettingsDialog(wxWindow* win)
{
    SetExtraStyle(wxDIALOG_EX_CONTEXTHELP|wxWS_EX_VALIDATE_RECURSIVELY);


    SetSheetStyle(wxPROPSHEET_BUTTONTOOLBOOK);
    SetSheetInnerBorder(0);
    SetSheetOuterBorder(0);

        // create a dummy image list with a few icons
    const wxSize imageSize(32, 32);

    wxString pixmapDir = Impp::exemplar()->getPixmapsDir();


    m_imageList = new wxImageList(imageSize.GetWidth(), imageSize.GetHeight());
    m_imageList->Add(wxBitmap(wxString::Format(wxT("%s/%s"), pixmapDir.c_str(), wxT("icons/settings/icq.png")),wxBITMAP_TYPE_PNG));
    m_imageList->Add(wxBitmap(wxString::Format(wxT("%s/%s"), pixmapDir.c_str(), wxT("icons/settings/buddylist.png")),wxBITMAP_TYPE_PNG));
    m_imageList->Add(wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, imageSize));
    m_imageList->Add(wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, imageSize));



    Create(win, wxID_ANY, _("Preferences"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE);

    CreateButtons(wxOK | wxCANCEL );


    wxBookCtrlBase* notebook = GetBookCtrl();
    notebook->SetImageList(m_imageList);



    notebook->AddPage(CreateOscarSettingsPage(notebook), _("ICQ"), true, 0);

    std::vector<SettingsPage*> sPages = Impp::exemplar()->getSettings()->getSettingPages();
    std::vector<SettingsPage*>::const_iterator iPage;

    int i = 1;
    for(iPage = sPages.begin(); iPage != sPages.end(); iPage++){
    	notebook->AddPage(CreatePageBySettingsPage(notebook, *iPage),(*iPage)->getLabel(), false, 3);
    	i++;
    }


    LayoutDialog();
}

SettingsDialog::~SettingsDialog()
{
    delete m_imageList;

	std::vector<GSetting*>::iterator iter(settings.begin());
	while(iter != settings.end()) {
		delete *iter;
		iter++;
	}
}

wxPanel* SettingsDialog::CreateOscarSettingsPage(wxWindow* parent)
{
/*
    wxPanel* panel = new wxPanel(parent);

    wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
    wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );

    //AccountBox
    wxBoxSizer* accountBox = createSettingsGroup(panel,wxT("Account:"));

    DBModule oscar = Impp::exemplar()->getDatabase()->getModule(wxT("Oscar"));

    //wxSizer* screenName = createTextPreference(panel,wxT("ICQ-Number: "),oscar,wxT("screenName"), ID_OSCAR_SCREENNAME);
    //accountBox->Add(screenName,1, wxGROW|wxALIGN_CENTRE|wxALL, 5 );
    //wxSizer* password = createTextPreference(panel,wxT("Password: "),oscar,wxT("password"), ID_OSCAR_PASSWORD, wxTE_PASSWORD);
    //accountBox->Add(password,1, wxGROW|wxALIGN_CENTRE|wxALL, 5 );

    item0->Add(accountBox,1, wxGROW|wxALIGN_CENTRE|wxALL, 5 );




    //final Layout
    topSizer->Add( item0, 1, wxGROW|wxALIGN_CENTRE|wxALL, 5 );
    topSizer->AddSpacer(5);

    panel->SetSizer(topSizer);
    topSizer->Fit(panel);
*/

    return new AccountPanel(parent);
}


wxPanel* SettingsDialog::CreatePageBySettingsPage(wxWindow* parent, SettingsPage* sPage){
	DBModule module = sPage->getDBModule();

    wxPanel* panel = new wxPanel(parent);

    wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
    wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );


    std::vector<SettingsGroup*> sGroups = sPage->getSettingsGroups();
    std::vector<SettingsGroup*>::const_iterator iGroup = sGroups.begin();

    while(iGroup != sGroups.end()){
    	SettingsGroup* sGroup = *iGroup;

        wxBoxSizer* groupSizer = createSettingsGroup(panel,sGroup->getLabel());

        std::vector<Setting*> settings = sGroup->getSettings();
        std::vector<Setting*>::iterator iSetting(settings.begin());

        while(iSetting != settings.end()){
        	Setting* setting = *iSetting;
        	if(CheckSetting* cs = dynamic_cast<CheckSetting*>(setting)){
        		wxCheckBox* cb = createCheckPreference(panel,cs,wxID_ANY);
        	    groupSizer->Add(cb,0, wxSHAPED|wxALL, 5 );
        	}else if(ChooseSetting* cs = dynamic_cast<ChooseSetting*>(setting)){
        		wxComboBox* box = createOptionPreference(panel, cs,wxID_ANY);
        		groupSizer->Add(box,0, wxSHAPED|wxALL, 5 );
        	}
        	iSetting++;
        }

        item0->Add(groupSizer,1, wxSHAPED|wxALL, 5 );
    	iGroup++;
    }

    //final Layout
    topSizer->Add( item0, 1, wxEXPAND|wxALL, 5 );
    topSizer->AddSpacer(5);

    panel->SetSizer(topSizer);
    topSizer->Fit(panel);

    return panel;
}

wxBoxSizer* SettingsDialog::createSettingsGroup(wxWindow* parent, const wxString & label){
    wxStaticBox* staticBox = new wxStaticBox(parent, wxID_ANY,label);
    wxBoxSizer* sizer = new wxStaticBoxSizer( staticBox, wxVERTICAL );
    return sizer;
}

wxSizer* SettingsDialog::createTextPreference(wxWindow* parent,const wxString & label,const DBModule & dbModule,const wxString & dbValue, const int & id, const long & flags){
    //the sizer
    wxBoxSizer* prefSizer = new wxBoxSizer( wxHORIZONTAL );
    //label
    prefSizer->Add(new wxStaticText(parent, wxID_ANY, label), 0, wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 1);
    //valuebox
    wxString value = dbModule.getStringValue(dbValue,wxEmptyString);

    wxTextCtrl* valueCtrl = new wxTextCtrl(parent,wxID_ANY,value,wxDefaultPosition,wxSize(150,wxDefaultCoord),flags);
    prefSizer->Add(2, 5, 1, wxALL, 0);
    prefSizer->Add(valueCtrl,0,wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL,1);

    GTextSetting* setting = new GTextSetting(id,valueCtrl,value, NULL);
    settings.push_back(setting);

    return prefSizer;
}

wxCheckBox* SettingsDialog::createCheckPreference(wxWindow* parent,const wxString & label,const DBModule & dbModule,const wxString & dbValue, const int & id, const long & flags){

	bool isChecked = dbModule.getIntValue(dbValue,0);
	wxCheckBox* checkBox = new wxCheckBox(parent,id,label,wxDefaultPosition,wxDefaultSize,flags);
	checkBox->SetValue(isChecked);

	GCheckSetting* setting = new GCheckSetting(id,checkBox,isChecked, NULL);
	settings.push_back(setting);

	return checkBox;


}

wxCheckBox* SettingsDialog::createCheckPreference(wxWindow* parent,CheckSetting* setting, const int & id, const long & flags){
	bool isChecked = setting->getModule().getIntValue(setting->getSettingName(),0);
	wxCheckBox* checkBox = new wxCheckBox(parent,id,setting->getLabel(),wxDefaultPosition,wxDefaultSize,flags);
	checkBox->SetValue(isChecked);

	GCheckSetting* gsetting = new GCheckSetting(id,checkBox,isChecked, setting);
	settings.push_back(gsetting);

	return checkBox;
}

wxComboBox* SettingsDialog::createOptionPreference(wxWindow* parent,const wxString & label,const DBModule & dbModule,const wxString & dbValue,const OptionPair* options, const int & optionsCount, const int & id, const long & flags){

	wxString defaultv = dbModule.getStringValue(dbValue,wxEmptyString);

	wxString* array = new wxString[optionsCount];
	OptionPair* opSettings = new OptionPair[optionsCount];
	int selected = 0;



	for(int i=0; i < optionsCount; i++){
		array[i]=options[i].displayName;
		if(defaultv == options[i].value){
			selected=i;
		}
		opSettings[i] = options[i];
	}

	wxComboBox* comboBox = new wxComboBox(parent,id,wxEmptyString,wxDefaultPosition,wxDefaultSize,optionsCount,array,flags);
	delete[] array;
	comboBox->SetSelection(selected);

	GOptionsSetting* setting = new GOptionsSetting(id,comboBox,selected,opSettings,optionsCount, NULL);
	settings.push_back(setting);
	return comboBox;
}

wxComboBox* SettingsDialog::createOptionPreference(wxWindow* parent, ChooseSetting* setting, const int & id, const long & flags){

	wxString defaultv = setting->getModule().getStringValue(setting->getSettingName(),wxEmptyString);

	std::vector<ChooseSettingPair> options = setting->getChoises();

	wxString* array = new wxString[options.size()];
	OptionPair* opSettings = new OptionPair[options.size()];
	int selected = 0;

	for(size_t i=0; i < options.size(); i++){
		array[i]=options[i].getLabel();
		if(defaultv == options[i].getValue()){
			selected=i;
		}
		opSettings[i] = OptionPair(options[i].getLabel(), options[i].getValue());
	}

	wxComboBox* comboBox = new wxComboBox(parent,id,wxEmptyString,wxDefaultPosition,wxDefaultSize,options.size(),array,flags);
	delete[] array;
	comboBox->SetSelection(selected);

	GOptionsSetting* gsetting = new GOptionsSetting(id,comboBox,selected,opSettings,options.size(), setting);
	settings.push_back(gsetting);
	return comboBox;

}

void SettingsDialog::onOk(wxCommandEvent & event){
	//wxLogDebug(wxT("okPressed"));
	std::vector<GSetting*>::iterator iter(settings.begin());
	while(iter != settings.end()) {
		(*iter)->processChanged();
		iter++;
	}
	event.Skip();
}


/*
Settings::Settings(wxWindow* parent) :
	wxFrame(parent, wxID_PREFERENCES, wxString(wxT("Settings")),wxDefaultPosition,wxDefaultSize)
{
	pages = new wxListbook(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLB_TOP);
	OscarSettings* oscarSettings = new OscarSettings(pages);
	pages->AddPage(oscarSettings,wxT("ICQ"),true);
	CenterOnScreen();
	Show(true);
}

Settings::~Settings()
{
}



OscarSettings::OscarSettings(wxWindow* parent) :
	wxPanel(parent, wxID_ANY){

    wxPanel* fields = new wxPanel(this);

    wxGridSizer* fieldSizer = new wxGridSizer(2,2,5,5);

    wxStaticText* labScreenName = new wxStaticText(fields,wxID_ANY,_T("Account-Name (ICQ No):"));
    fieldSizer->Add(labScreenName,1,wxEXPAND);

    txtScreenName = new wxTextCtrl(fields,wxID_ANY,wxEmptyString,wxDefaultPosition,wxDefaultSize,0,wxTextValidator(wxFILTER_ALPHANUMERIC|wxFILTER_NUMERIC));
    fieldSizer->Add(txtScreenName,1,wxEXPAND);

    wxStaticText* lavPw = new wxStaticText(fields,wxID_ANY,_T("Password: "));
    fieldSizer->Add(lavPw,1,wxEXPAND);

    txtPW = new wxTextCtrl(fields,wxID_ANY,wxEmptyString,wxDefaultPosition,wxDefaultSize,wxTE_PASSWORD);
    fieldSizer->Add(txtPW,1,wxEXPAND);

    fields->SetSizer(fieldSizer);
    Layout();
}

OscarSettings::~OscarSettings()
{
}
*/

IMPLEMENT_DYNAMIC_CLASS(StdSettingsDialogModule, wxEvtHandler)

void StdSettingsDialogModule::moduleInit(){
	//register Event handler
	Impp* impp = Impp::exemplar();
	impp->Connect(wxID_ANY,EVT_IMPP_COMMAND, ImppCommandEventHandler(StdSettingsDialogModule::onImppCommand), NULL, this);

	iUserInterface* ui = impp->getModuleManager()->getUserInterfaceModule();
	if(ui != NULL){
		ui->reigsterMainMenuEntryAdder(STD_SETTINGS_DIALOG_MODULE_NAME, StdSettingsDialogModule::addMainMenuItem);


#ifdef __WXGTK__
	iIcons* icons = ui->getIcons();
	icons->registerActionIcon(STD_SETTINGS_DIALOG_MODULE_NAME, STD_SETTINGS_DIALOG_MODULE_ACTION_SHOW, wxArtProvider::GetBitmap(wxT(GTK_STOCK_PREFERENCES), wxART_MENU, wxSize(-1,-1)));
#endif

	}else{
		wxLogDebug(wxT("StdSettingsDialogHandler: No UserInterface found to add Buddy Menu entry!"));
	}
}

void StdSettingsDialogModule::onImppCommand(ImppCommandEvent & event){
	event.Skip();
	if(event.getModuleName() == STD_SETTINGS_DIALOG_MODULE_NAME){
		if(event.getActionName() == STD_SETTINGS_DIALOG_MODULE_ACTION_SHOW){
			iBuddyList* bl = Impp::exemplar()->getModuleManager()->getBuddyListModule();
			if(bl != NULL){
				SettingsDialog* dialog = new SettingsDialog(bl->getWindow());
				dialog->Show();
			}else{
				wxLogDebug(wxT("StdSettingsDialogHandler: No Buddylist found to show Preferences!"));
			}

		}
	}
}

void wxCALLBACK StdSettingsDialogModule::addMainMenuItem(iMenu* menu, void* ptr){
	menu->appendItem(STD_SETTINGS_DIALOG_MODULE_ACTION_SHOW, wxT("Preferences"), 60, wxT("Preferences"));
}

}
